const path = require('path')
const { decrypter, subkeyconstructioner } = require('./DES/index')
const { RECORD_DIR, printTip } = require('./config.js')

const { parentPort } = require("worker_threads");

/**
 * 解密
 * @param {*} beginPos 开始位置
 * @param {*} endPos 结束位置
 * @returns 计算结果
 */
function decrypteFactory(options) {
  const { beginPos/* 开始位置 */,
    endPos/* 结束位置 */,
    KBinary/* 已知的密钥（二进制） */,
    length/* 密钥未知部分的长度 */,
    ciphertext/*密文 */,
  } = options

  const arr = []

  for (let index = +beginPos; index < +endPos; index++) {
    const startTimestamp = Date.now();

    let b = to2(index, length) // 返回7位二进制
    b = fillCheckBit1(b) // 填充 校验位
    const hypothesisKey = KBinary + b

    // 构建子密钥组
    const subkeyArr = subkeyconstructioner(hypothesisKey)

    const result = decrypter(ciphertext, subkeyArr)

    // 校验
    const verify = textVerify(result)

    const endTimestamp = Date.now();
    const spendTime = endTimestamp - startTimestamp

    arr.push({
      number: index, // 计算的值
      SerialNumber: index - beginPos + 1, // 序号
      hypothesisKey,
      result,
      verify,
      spendTime,
    })
  }

  parentPort.postMessage(arr);
}


/**
 * 对解密后得内容进行 明文校验
 * @param text 解密后的内容
 * @returns 正确 true, 错误 false
 */
function textVerify(text) {
  const regExp = /^[1-9a-zA-Z?!:';.,]*$/g
  const result = text.match(regExp)
  return result !== null ? true : false
}

/**
 * 填充校验位，方案1，直接补0
 * @param binary 
 * @returns 
 */
function fillCheckBit1(binary) {
  let result = ''
  for (let i = 0; i < binary.length / 7; i++) {
    let value = binary.substring(i * 7, (1 + i) * 7)
    result += value + '0'
  }

  return result
}

/**
 * 这个方法是提供给 to2 的
 * @param num 
 * @deprecated 不要使用，使用 to2 方法
 * @returns 
 */
function DecimalTransformBinary(num) {
  if (num === 0 || num === 1) return num + ''
  // 余数
  const remainder = num % 2 + ''
  const result = Math.floor(num / 2)

  return DecimalTransformBinary(result) + remainder
}

/**
 * 一个 10 进制 转 2进制
 * @param num 
 * @param 二进制总长度 
 * @returns 
 */
function to2(num, length) {
  let result = DecimalTransformBinary(num)
  const zeros = '0000000000000000000000000000000000000000000000000000000000000000'
  const shortNum = length - result.length
  result = zeros.substring(0, shortNum) + result
  return result
}

parentPort.on("message", (params) => {
  // const result = de(params);
  // parentPort.postMessage(result);
  decrypteFactory(params)
});